from django.db import transaction
from rest_framework import serializers
from apps.goods.models import SKU, GoodsCategory, SPU, SPUSpecification, SpecificationOption, SKUSpecification


class SKUSpecificationSerializer(serializers.ModelSerializer):
    spec_id = serializers.IntegerField()
    option_id = serializers.IntegerField()
    class Meta:
        model = SKUSpecification
        fields = ['spec_id', 'option_id']

class SKUListSerializer(serializers.ModelSerializer):
    # 前端提交的数据格式和序列化器默认验证字段不符， 需要重新定义字段
    # category_id: 115
    # spu_id: 2
    spu_id = serializers.IntegerField()
    category_id = serializers.IntegerField()

    # 为了更新和查询显示数据需要重写下面两个字段
    # category ， spu
    category = serializers.StringRelatedField()
    spu = serializers.StringRelatedField()
    specs = SKUSpecificationSerializer(many=True)

    class Meta:
        model = SKU
        fields = '__all__'

    # 前端有传递规格和规格选项信息，但是数据库在保存数据的时候, 并没有写入SKU的规格和规格选项信息
    def create(self, validated_data):
        specs_data = validated_data.pop('specs')
        with transaction.atomic():
            # 开启事务
            save_point = transaction.savepoint()
            sku = SKU.objects.create(**validated_data)
            # with语句会自动回滚，看需求决定是否写回滚语句
            for spec in specs_data:
                SKUSpecification.objects.create(sku=sku, **spec)

            transaction.savepoint_commit(save_point)
        return sku


    def update(self, instance, validated_data):
        # instance：要更新的对象      validated_data：更新的数据
        # 将嵌套数据pop出去
        # 外层sku更新
        # 内层sku规格和规格选项更新
        spec_data = validated_data.pop('specs')
        super().update(instance,validated_data)
        for spec in spec_data:
            SKUSpecification.objects.filter(sku=instance, spec_id=spec.get('spec_id')).update(option_id=spec.get('option_id'))
        return instance

class GoodsCategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = GoodsCategory
        fields = ['id', 'name']

class SPUSimpleSerializer(serializers.ModelSerializer):
    class Meta:
        model = SPU
        fields = ['id', 'name']

class OptionsSerializer(serializers.ModelSerializer):
    class Meta:
        model = SpecificationOption
        fields = ['id', 'value']

class SPUSpecSerializer(serializers.ModelSerializer):
    # 根据模型中隐藏字段，获取规格选项信息
    options = OptionsSerializer(many=True)
    class Meta:
        model = SPUSpecification
        fields = ['id', 'name', 'options']
